/*
 *  complex.cpp
 *  Perceel
 *
 *  Created by Nicola Gigante on 15/04/08.
 *  Copyright 2008 Nicola Gigante. All rights reserved.
 *
 */

#include "complex.h"
#include <cstring>


#ifdef Q_CC_MSVC 

#define snprintf _snprintf_s

bool signbit(Real);

bool signbit(Real r)
{
	if(-r < r)
		return true;
	else
		return false;
}

#endif

bool realEqual(Real r1, Real r2)
{
	const Real aprox = 1E9;

	if(signbit(r1) != signbit(r2))
		return false;
	
	char r1str[20], r2str[20];
	snprintf(r1str, 20, "%e", floor(fabs(r1)*aprox));
	snprintf(r2str, 20, "%e", floor(fabs(r2)*aprox));
	
	return strcmp(r1str, r2str) == 0;
}

bool complexEqual(const Complex &c1, const Complex &c2)
{      
	const Real aprox = 1E9;
	char c1_str[50], c2_str[50];
	
	Real r1 = fabs(real(c1));
	Real r2 = fabs(real(c2));
	Real i1 = fabs(imag(c1));
	Real i2 = fabs(imag(c2));
	
	r1 = floor(r1*aprox);
	r2 = floor(r2*aprox);
	i1 = floor(i1*aprox);
	i2 = floor(i2*aprox);
	
	snprintf(c1_str, 50, "%e %e", r1, i1);
	snprintf(c2_str, 50, "%e %e", r2, i2);
	
	return (strcmp(c1_str, c2_str) == 0);
}


bool isReal(const Complex &c)
{
	return fabs(imag(c)) < 1E-5;
}

QString complexToString(const Complex &c, const QString &var)
{
	QString str = "";
	if(real(c) != 0)
		str += QString("%1").arg(real(c), 3, 'g');
	if(imag(c) != 0)
		str += QString(" %1 %2 %3").arg(imag(c) < 0 ? '-' : '+').arg(var).arg(fabs(imag(c)), 3, 'g');
	if(str.isEmpty())
		str = "0";
	
	return str;
}

//bool operator==(const Complex &c1, const Complex &c2)
//{
//	//return realEqual(real(c1), real(c2)) && realEqual(imag(c1), imag(c2));
//	return complexEqual(c1, c2);
//}

bool operator!=(const Complex &c1, const Complex &c2)
{
	return !(c1 == c2);
}

bool operator<(const Complex &c1, const Complex &c2)
{
	if(real(c1) < real(c2))
		return true;
	else if(realEqual(real(c1), real(c2)))
		if(imag(c1) < imag(c2))
			return true;
		else
			return false;
	else
		return false;
}

bool operator>(const Complex &c1, const Complex &c2)
{
	return !(c1 < c2 || c1 == c2);
}